#ifndef AIPROCESS_H
#define AIPROCESS_H

#include <QMutex>
#include <QObject>
#include "dualdetect.h"
#include "imagerecord.h"
#include "patchcoreai.h"
#include <QPointF>
#include <QVector2D>
#include <QPolygonF>
#include "quicktool.h"
#include "AutoPropertyHelper.h"

class DualDetect;


class AIprocess : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QVariantList shieldAreaList READ shieldAreaList NOTIFY shieldAreaListChange)
    Q_PROPERTY(bool isInit READ isInit NOTIFY isInitChange)
    Q_PROPERTY(QVariantList modelInputSize READ modelInputSize NOTIFY modelInputSizeChange)
    Q_PROPERTY(int modelDataSize READ modelDataSize NOTIFY modelDataSizeChange)
    Q_PROPERTY(QString modelName READ modelName NOTIFY modelNameChange)
    Q_PROPERTY(QString SDKversion READ SDKversion NOTIFY SDKversionChange)
    Q_PROPERTY(float objThresh READ objThresh WRITE setobjThresh NOTIFY objThreshChanged)
    Q_PROPERTY(float nmsThresh READ nmsThresh WRITE setnmsThresh NOTIFY nmsThreshChange)
    //0yolo 1patchcore
    Q_PROPERTY(int modelType READ modelType NOTIFY modelTypeChange)
    //PatchCore特有的


    // {"name", "待"},{"size", 0},{"type", "FP16"},{"coreSet", 0}
    Q_PROPERTY(QVariantMap coreSetDetal READ coreSetDetal NOTIFY coreSetDetalChange)
    Q_PROPERTY(QVariantMap modelDetal READ modelDetal NOTIFY modelDetalChange)
    //[{"istrain":true,"img":001.jpg},{"istrain":true,"img":001.jpg}..]
    Q_PROPERTY(QVariantList imageInfoList READ imageInfoList NOTIFY imageInfoListChange)
    Q_PROPERTY(bool canRun READ canRun NOTIFY canRunChange)
    //0～1
    Q_PROPERTY(float currentSchedule READ currentSchedule NOTIFY currentScheduleChange)

    Q_PROPERTY(QVariantMap defectEnable READ defectEnable WRITE setdefectEnable NOTIFY defectEnableChange)

    //Q_PROPERTY(QVariantMap defectEnable READ defectEnable WRITE setdefectEnable NOTIFY defectEnableChange)

public:
    enum AIModel
    {
        noneModel,
        yoloModel,
        PatchCoreModel,
    };


    static  AIprocess &getInstance();
    Q_INVOKABLE void initialize(QString modlePath = "master/test/best_rknnAfter.rknn");
    Q_INVOKABLE void delshieldAreaList(int index);
    Q_INVOKABLE void addshieldAreaList(int defect,int x,int y,int wid,int hei);

    GLOBAL_QML_STATE_PROPERTY(QVariantList,polygonDefect,{})
    Q_INVOKABLE void addshieldimutant(int defect,QVariantList Area);
    Q_INVOKABLE void delshieldimutant(int index);

    //PatchCore特有的
    // Q_INVOKABLE void show
    Q_INVOKABLE void loadCoreSet();
    Q_INVOKABLE void addTrainImage();
    Q_INVOKABLE void delTrainImage(int index);
    Q_INVOKABLE void clearTrainImage();
    Q_INVOKABLE void autoTrain();
    Q_INVOKABLE void stopTrain();

    Q_INVOKABLE void setAIroi(int x, int y ,int wid, int hei);
    Q_INVOKABLE void resetAIroi();

    AUTO_CONFIG_PROPERTY(AIprocess,"yoloDetection",float,dirtyThreshold)
    AUTO_CONFIG_PROPERTY(AIprocess,"yoloDetection",float,dirtysize)
    AUTO_CONFIG_PROPERTY(AIprocess,"yoloDetection",float,dirtyGradThreshold)
    AUTO_CONFIG_PROPERTY(AIprocess,"yoloDetection",bool,dirtyisWhite)

    void processImg(ImageRecord &imgcard );


    bool isInit() const {return isInit_;};
    void setIsInit(bool isInit);

    float objThresh();
    void setobjThresh(float objThresh);
    float nmsThresh();
    void  setnmsThresh(float nmsThresh);

    QVariantMap defectEnable() const {return defectEnable_;};
    void setdefectEnable(QVariantMap defectEnable);


    QVariantList shieldAreaList() const {return shieldAreaList_;};



    QVariantList modelInputSize() const {return modelInputSize_;};
    int modelDataSize() const {return modelDataSize_;};
    QString modelName() const {return modelName_;};
    QString SDKversion() const {return SDKversion_;};

    int modelType() const {return static_cast<int>(modelType_);};
    QVariantMap coreSetDetal(){return patchCoreAi_.coreSetDetal;};
    QVariantMap modelDetal(){return patchCoreAi_.modelDetal;};
    QVariantList imageInfoList() {return patchCoreAi_.imageInfoList;};
    bool canRun() const {return patchCoreAi_.canRun;};
    float currentSchedule() const {return patchCoreAi_.currentSchedule;};

public slots:
    void configDataChanged(QString Category,QString key);
    void valueTableLoad();

signals:
    void shieldAreaListChange();
    void isInitChange();
    void modelInputSizeChange();
    void modelDataSizeChange();
    void modelNameChange();
    void SDKversionChange();
    void objThreshChanged();
    void nmsThreshChange();
    void loadCompele();
    //patch特有
    void coreSetDetalChange();
    void imageInfoListChange();
    void canRunChange();
    void currentScheduleChange();
    void finishTrain();
    void alreadyTrain();
    void startTrain();
    void modelTypeChange();
    void modelDetalChange();

    void defectEnableChange();
private:
    //QMutex modelInitMutex_;
    QMutex modelMutex_;
    float objThresh_;
    float confidenceThreshold;
    float nmsThreshold;
    QVariantList modelInputSize_;
    QVariantMap defectEnable_;
    int modelDataSize_;
    QString SDKversion_;
    QString modelName_;
    QVariantList shieldAreaList_;
    QList<QPolygonF> polygonVariant_;
    rknn_sdk_version version;
    AIModel modelType_;
    cv::Rect aiRoi;

    bool isInit_ ;
    AIprocess(QObject *parent = nullptr);
    AIprocess& operator=(const AIprocess& rhs) = delete;

    DualDetect *dualDetect_;
    PatchCoreAi patchCoreAi_;
    QString extractModelName(const QString &modelPath);
    bool isBoxInShieldAreaList(const QVariantList &shieldAreaList, const object_detect_result &det_result);

    //PatchCore特有
    bool isTrain = false;
};


int testAIprocess();

#endif // AIPROCESS_H
